import requests
import json
import uuid
import threading
import time
from datetime import datetime
from typing import Dict, List, Optional
import os

from src.models.metaso_data import MetasoQueryData, MetasoWebpageData
from src.models.database import db
from src.services.llm_service import LLMService
from flask import current_app, copy_current_request_context


class MetasoService:
    """Metaso数据查询服务"""
    
    def __init__(self):
        self.llm_service = LLMService()
        self.running_tasks = {}
        self.session = requests.Session()
        
        # Metaso API配置
        self.metaso_api_key = os.getenv("METASO_API_KEY", "mk-3B410B7899F0522A7074EF1CF23D1026")
        self.metaso_base_url = os.getenv("METASO_BASE_URL", "https://metaso.cn/api/v1/chat/completions")
        
        # 设置请求头
        self.session.headers.update({
            'Authorization': f'Bearer {self.metaso_api_key}',
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        })
    
    def start_query_task(self, query_text: str, sector_id: str = None, sector_name: str = None) -> str:
        """启动Metaso查询任务"""
        task_id = str(uuid.uuid4())
        
        # 立即在数据库中创建查询记录
        try:
            query_data = MetasoQueryData(
                query_id=task_id,
                query_text=query_text,
                query_time=datetime.now(),
                total_results=0,
                credits_used=0,
                status='pending',
                sector_id=sector_id,
                sector_name=sector_name
            )
            
            db.session.add(query_data)
            db.session.commit()
            print(f"✅ 查询任务已创建: {task_id}")
            
        except Exception as e:
            print(f"❌ 创建查询任务失败: {str(e)}")
            db.session.rollback()
            raise e
        
        # 获取当前应用上下文
        app = current_app._get_current_object()
        
        def run_query():
            # 在后台线程中需要应用上下文
            with app.app_context():
                try:
                    self._execute_query_task(task_id, query_text)
                except Exception as e:
                    print(f"Metaso查询任务失败 {task_id}: {str(e)}")
                    self._update_task_status(task_id, 'failed', error_message=str(e))
        
        # 在新线程中运行查询任务
        thread = threading.Thread(target=run_query)
        thread.daemon = True
        thread.start()
        
        self.running_tasks[task_id] = {
            'thread': thread,
            'status': 'running',
            'query_text': query_text,
            'sector_id': sector_id,
            'sector_name': sector_name,
            'started_at': datetime.now()
        }
        
        return task_id
    
    def _execute_query_task(self, task_id: str, query_text: str):
        """执行Metaso查询任务"""
        try:
            # 1. 更新状态为运行中
            self._update_database_status(task_id, 'running')
            
            # 2. 调用Metaso API
            print(f"🚀 开始执行Metaso查询: {task_id}")
            print(f"📝 查询内容: {query_text[:100]}...")
            
            metaso_response = self._call_metaso_api(query_text)
            
            if not metaso_response:
                raise Exception("Metaso API调用失败")
            
            print(f"✅ Metaso API调用成功: {task_id}")
            
            # 3. 更新数据库中的查询结果
            self._update_query_result(task_id, metaso_response)
            
            # 4. 执行AI分析（新增步骤）
            self._perform_ai_analysis(task_id)
            
            # 5. 更新任务状态为完成
            self._update_database_status(task_id, 'completed')
            self._update_task_status(task_id, 'completed')
            
            print(f"🎉 Metaso查询任务完成: {task_id}")
            
        except Exception as e:
            print(f"❌ Metaso查询任务执行失败 {task_id}: {str(e)}")
            self._update_database_status(task_id, 'failed', str(e))
            self._update_task_status(task_id, 'failed', error_message=str(e))
            raise e
    
    def _call_metaso_api(self, query_text: str, model: str = "fast_thinking", format_type: str = "simple") -> Optional[Dict]:
        """调用Metaso API"""
        try:
            payload = {
                "q": query_text,
                "model": model,
                "format": format_type,
                "conciseSnippet": True
            }
            
            response = self.session.post(
                self.metaso_base_url,
                json=payload,
                timeout=30
            )
            
            if response.status_code == 200:
                return response.json()
            else:
                print(f"Metaso API调用失败: {response.status_code} - {response.text}")
                return None
                
        except Exception as e:
            print(f"调用Metaso API时发生错误: {str(e)}")
            return None
    
    def _update_database_status(self, task_id: str, status: str, error_message: str = None):
        """更新数据库中的任务状态"""
        try:
            query_data = MetasoQueryData.query.filter_by(query_id=task_id).first()
            if query_data:
                query_data.status = status
                query_data.updated_at = datetime.now()
                
                if error_message:
                    query_data.error_message = error_message
                
                db.session.commit()
                print(f"📊 数据库状态更新: {task_id} -> {status}")
            else:
                print(f"⚠️ 未找到查询记录: {task_id}")
                
        except Exception as e:
            db.session.rollback()
            print(f"❌ 更新数据库状态失败: {str(e)}")
    
    def _update_query_result(self, task_id: str, metaso_response: Dict):
        """更新查询结果到数据库"""
        try:
            query_data = MetasoQueryData.query.filter_by(query_id=task_id).first()
            if query_data:
                # 更新主查询结果
                query_data.analysis_result = metaso_response.get('answer', '')
                query_data.analysis_time = datetime.now()
                query_data.confidence_score = 0.9  # Metaso直接回答的置信度较高
                query_data.credits_used = metaso_response.get('credits', 0)
                query_data.updated_at = datetime.now()
                
                # 处理sources数据
                sources = metaso_response.get('sources', [])
                query_data.total_results = len(sources)
                
                # 保存sources到metaso_webpage_data表
                if sources:
                    self._save_sources_data(query_data.id, sources)
                
                db.session.commit()
                print(f"💾 查询结果已保存到数据库: {task_id}")
                print(f"📄 保存了 {len(sources)} 条来源数据")
            else:
                print(f"⚠️ 未找到查询记录: {task_id}")
                
        except Exception as e:
            db.session.rollback()
            print(f"❌ 保存查询结果失败: {str(e)}")
            raise e
    
    def _save_sources_data(self, query_data_id: int, sources: List[Dict]):
        """保存sources数据到metaso_webpage_data表（不删除旧数据）"""
        try:
            # 直接保存新的sources数据，不删除旧数据
            for position, source in enumerate(sources, 1):  # position从1开始
                webpage_data = MetasoWebpageData(
                    query_data_id=query_data_id,
                    position=position,
                    title=source.get('title', ''),
                    link=source.get('link', ''),
                    snippet=source.get('snippet', ''),
                    score='',  # 新格式中没有score字段
                    date=source.get('date', '')
                )
                
                db.session.add(webpage_data)
            
            print(f"📚 成功保存 {len(sources)} 条来源数据（追加模式）")
            
        except Exception as e:
            print(f"❌ 保存来源数据失败: {str(e)}")
            raise e
    
    def _perform_ai_analysis(self, task_id: str):
        """执行AI分析，提取CAGR数据"""
        try:
            query_data = MetasoQueryData.query.filter_by(query_id=task_id).first()
            if not query_data or not query_data.analysis_result:
                print(f"⚠️ 未找到查询数据或analysis_result为空: {task_id}")
                return
            
            print(f"🤖 开始AI分析: {task_id} - {query_data.sector_name}")
            
            # 调用LLM服务进行分析
            analysis_result = self.llm_service.analyze_industry_cagr(
                query_data.analysis_result, 
                query_data.sector_name or "未知板块"
            )
            
            if analysis_result.get('success'):
                # 更新数据库
                query_data.industry_cagr = analysis_result.get('industry_cagr')
                query_data.market_stage_cagr = analysis_result.get('market_stage_cagr')
                query_data.ai_analysis_result = analysis_result.get('ai_analysis_result')
                query_data.updated_at = datetime.now()
                
                db.session.commit()
                print(f"✅ AI分析完成并保存: {task_id}")
                print(f"📊 行业CAGR: {analysis_result.get('industry_cagr')}%")
                print(f"📈 市场阶段CAGR: {analysis_result.get('market_stage_cagr')}%")
            else:
                print(f"❌ AI分析失败: {task_id} - {analysis_result.get('error')}")
                
        except Exception as e:
            print(f"❌ AI分析异常: {task_id} - {str(e)}")
            db.session.rollback()

    
    def query_industry_data_batch(self) -> Dict:
        """批量查询四个行业板块的数据"""
        queries = [
            {
                'id': 'pharma_formulations',
                'name': '人药制剂板块',
                'query': '请提供中国医药市场规模2025年和2030年的最新预测数据，以及复合年增长率(CAGR)是多少？生物药在2022-2026年的复合年增长率分别是多少？请提供具体数据来源。全球医药市场中，生物药、肿瘤治疗、基因/细胞疗法等创新领域的增长情况如何？新兴市场(如亚太、拉美)与发达国家的增速对比如何？，要尽量用最新一年的数据'
            },
            {
                'id': 'pharma_apis',
                'name': '人药原料药板块',
                'query': '请提供中国医药原料药市场的2025年和2030年的最新预测数据：2025-2030年原料药复合年增长率CAGR预测，在2022-2026年的复合年增长率分别是多少？以及相关政策对其的影响，请提供具体数据来源，要尽量用最新一年的数据。'
            },
            {
                'id': 'plant_protection',
                'name': '植保板块',
                'query': '请提供中国农药(植保)市场的2025年和2030年的最新预测数据：2025-2030年中国农药(植保)复合年增长率CAGR预测，在2022-2026年的复合年增长率分别是多少？以及相关政策对其的影响，请提供具体数据来源，要尽量用最新一年的数据。'
            },
            {
                'id': 'animal_health',
                'name': '动保板块',
                'query': '请提供中国兽药(动保)市场的2025年和2030年的最新预测数据：2025-2030年中国兽药(动保)复合年增长率CAGR预测，在2022-2026年的复合年增长率分别是多少？以及相关政策对其的影响，请提供具体数据来源，要尽量用最新一年的数据。'
            }
        ]
        
        task_ids = []
        for query_info in queries:
            task_id = self.start_query_task(
                query_info['query'], 
                sector_id=query_info['id'], 
                sector_name=query_info['name']
            )
            task_ids.append({
                'task_id': task_id,
                'sector_id': query_info['id'],
                'sector_name': query_info['name'],
                'query': query_info['query']
            })
        
        return {
            'batch_id': str(uuid.uuid4()),
            'tasks': task_ids,
            'total_tasks': len(task_ids),
            'status': 'running'
        }
    
    def get_batch_status(self, task_ids: List[str]) -> Dict:
        """获取批量查询任务的状态"""
        batch_status = {
            'completed': 0,
            'running': 0,
            'failed': 0,
            'tasks': []
        }
        
        for task_id in task_ids:
            status = self.get_query_task_status(task_id)
            batch_status['tasks'].append({
                'task_id': task_id,
                'status': status.get('status', 'unknown')
            })
            
            if status.get('status') == 'completed':
                batch_status['completed'] += 1
            elif status.get('status') == 'running':
                batch_status['running'] += 1
            elif status.get('status') == 'failed':
                batch_status['failed'] += 1
        
        # 计算整体状态
        if batch_status['completed'] == len(task_ids):
            batch_status['overall_status'] = 'completed'
        elif batch_status['failed'] == len(task_ids):
            batch_status['overall_status'] = 'failed'
        else:
            batch_status['overall_status'] = 'running'
        
        return batch_status
    

    
    def _update_task_status(self, task_id: str, status: str, error_message: str = None):
        """更新任务状态"""
        if task_id in self.running_tasks:
            self.running_tasks[task_id]['status'] = status
            if error_message:
                self.running_tasks[task_id]['error_message'] = error_message
            if status in ['completed', 'failed']:
                self.running_tasks[task_id]['completed_at'] = datetime.now()
    
    def get_query_task_status(self, task_id: str) -> Dict:
        """获取查询任务状态"""
        if task_id in self.running_tasks:
            return self.running_tasks[task_id]
        else:
            return {'status': 'not_found', 'message': '任务不存在'}
    
    def get_query_data(self, query_id: str) -> Optional[Dict]:
        """获取查询数据"""
        try:
            query_data = MetasoQueryData.query.filter_by(query_id=query_id).first()
            if query_data:
                result = query_data.to_dict()
                
                # 获取关联的来源数据（sources）
                sources = MetasoWebpageData.query.filter_by(
                    query_data_id=query_data.id
                ).order_by(MetasoWebpageData.position).all()
                
                result['sources'] = [source.to_dict() for source in sources]
                result['sources_count'] = len(sources)
                
                return result
            
            return None
            
        except Exception as e:
            print(f"获取查询数据失败: {str(e)}")
            return None
    
    def get_all_queries(self, limit: int = 50) -> List[Dict]:
        """获取所有查询记录"""
        try:
            queries = MetasoQueryData.query.order_by(
                MetasoQueryData.created_at.desc()
            ).limit(limit).all()
            
            return [query.to_dict() for query in queries]
            
        except Exception as e:
            print(f"获取查询记录失败: {str(e)}")
            return []
    
    def cancel_query_task(self, task_id: str) -> bool:
        """取消查询任务"""
        if task_id in self.running_tasks:
            self.running_tasks[task_id]['status'] = 'cancelled'
            return True
        return False
    
    def search_by_keywords(self, keywords: List[str], limit: int = 20) -> List[Dict]:
        """根据关键词搜索历史查询"""
        try:
            # 构建搜索条件
            search_conditions = []
            for keyword in keywords:
                search_conditions.append(
                    MetasoQueryData.query_text.contains(keyword)
                )
            
            # 执行搜索
            from sqlalchemy import or_
            queries = MetasoQueryData.query.filter(
                or_(*search_conditions)
            ).order_by(
                MetasoQueryData.created_at.desc()
            ).limit(limit).all()
            
            return [query.to_dict() for query in queries]
            
        except Exception as e:
            print(f"关键词搜索失败: {str(e)}")
            return []
    
    def get_statistics(self) -> Dict:
        """获取查询统计信息"""
        try:
            total_queries = MetasoQueryData.query.count()
            completed_queries = MetasoQueryData.query.filter_by(status='completed').count()
            failed_queries = MetasoQueryData.query.filter_by(status='failed').count()
            pending_queries = MetasoQueryData.query.filter_by(status='pending').count()
            
            # 按日期统计
            from sqlalchemy import func
            daily_stats = db.session.query(
                func.date(MetasoQueryData.created_at).label('date'),
                func.count(MetasoQueryData.id).label('count')
            ).group_by(
                func.date(MetasoQueryData.created_at)
            ).order_by(
                func.date(MetasoQueryData.created_at).desc()
            ).limit(7).all()
            
            return {
                'total_queries': total_queries,
                'completed_queries': completed_queries,
                'failed_queries': failed_queries,
                'pending_queries': pending_queries,
                'success_rate': (completed_queries / total_queries * 100) if total_queries > 0 else 0,
                'daily_stats': [
                    {'date': stat.date.isoformat(), 'count': stat.count}
                    for stat in daily_stats
                ]
            }
            
        except Exception as e:
            print(f"获取统计信息失败: {str(e)}")
            return {}
